package com.imooc.controller;

import com.imooc.BO.ShopCartBO;
import com.imooc.BO.SubmitOrderBO;
import com.imooc.constant.RedisConstant;
import com.imooc.enums.OrderStatusEnum;
import com.imooc.enums.PayMethod;
import com.imooc.pojo.OrderStatus;
import com.imooc.service.AddressService;
import com.imooc.service.OrderService;
import com.imooc.utils.CookieUtils;
import com.imooc.utils.IMOOCJSONResult;
import com.imooc.utils.JsonUtils;
import com.imooc.utils.RedisOperator;
import com.imooc.vo.MerchantOrdersVO;
import com.imooc.vo.OrderVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @author gcq
 * @Create 2022-01-08
 */
@Api(value = "订单相关", tags = {"订单相关API接口"})
@RestController
@RequestMapping("orders")
public class OrdersController extends BaseController{

    @Autowired
    private AddressService addressService;

    @Autowired
    OrderService orderService;

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    RedisOperator redisOperator;

    /**
     * 用户下单需要更改本地环境
     *      1、开启内网穿透环境 natapp
     *          1.1、前端请求接口地址更改为服务器地址
     *      2、更改BaseController 中 payReturnUrl 回调链接
     *      3、支付服务中心没有问题 能返回二维码
     *      4、手机支付完成后，将收到回调，内网穿透后 能接受到请求，然后进行处理
     *
     * @param submitOrderBO
     * @param request
     * @param response
     * @return
     */
    @ApiOperation(value = "用户下单", notes = "用户下单", httpMethod = "POST")
    @PostMapping("/create")
    public IMOOCJSONResult info(@RequestBody SubmitOrderBO submitOrderBO,
                                HttpServletRequest request,
                                HttpServletResponse response)
    {
        if(submitOrderBO.getPayMethod() != PayMethod.WEIXIN.type
            && submitOrderBO.getPayMethod() != PayMethod.ALIPAY.type) {
            return IMOOCJSONResult.ok("支付方式不支持");
        }

        String shopCartJson = redisOperator.get(RedisConstant.FOODIE_SHOP_CART + submitOrderBO.getUserId());
        if (StringUtils.isEmpty(shopCartJson)) {
            return IMOOCJSONResult.errorMsg("购物车数据不正确");
        }

        List<ShopCartBO> shopCartList = JsonUtils.jsonToList(shopCartJson, ShopCartBO.class);

        // 1、创建订单
        OrderVO orderVo = orderService.createOrder(submitOrderBO, shopCartList);
        String orderId = orderVo.getOrderId();

        // 2、创建订单之后，移除购物车中已结算的商品
        // 整合redis之后，完善购物车中一结算的商品清除，并且同步到前端cookie
        // 清理覆盖现有的redis购物数据
        shopCartList.removeAll(orderVo.getToBeRemovedShopCartList());
        redisOperator.set(RedisConstant.FOODIE_SHOP_CART + submitOrderBO.getUserId(), JsonUtils.objectToJson(shopCartList));

        // 清除 Cookie
        CookieUtils.setCookie(request, response, FOODIE_SHOPCART, JsonUtils.objectToJson(shopCartList), true);

        // 3、向支付中心发送当前订单，用于保存支付中心的订单数据
        MerchantOrdersVO merchantOrdersVO = orderVo.getMerchantOrdersVO();
        merchantOrdersVO.setReturnUrl(payReturnUrl);

        // 方便测试 订单金额都更改为0.01
        merchantOrdersVO.setAmount(1);

        // 3.1、设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("imoocUserId", "imooc");
        headers.add("password", "imooc");

        // 3.2、设置请求体
        HttpEntity<MerchantOrdersVO> entity =
                new HttpEntity<>(merchantOrdersVO, headers);

        // 3.3、发送请求获取结果
        ResponseEntity<IMOOCJSONResult> responseEntity =
                restTemplate.postForEntity(paymentUrl,
                                           entity,
                                           IMOOCJSONResult.class);
        IMOOCJSONResult paymentResult = responseEntity.getBody();
        if(paymentResult.getStatus() != 200) {
            return IMOOCJSONResult.errorMsg("支付中心订单创建失败，请联系管理员");
        }

        return IMOOCJSONResult.ok(orderId);
    }

    /**
     * 支付宝或微信支付 回调接口，用户支付完成后，支付系统回调该接口
     * @param merchantOrderId
     * @return
     */
    @ApiOperation(value = "通知商家订单已经支付", notes = "微信支付成功后回调，通知商家订单已经支付", httpMethod = "POST")
    @PostMapping("/notifyMerchantOrderPaid")
        public Integer notifyMerchantOrderPaid(String merchantOrderId)
    {
        orderService.updateOrderStatus(merchantOrderId, OrderStatusEnum.WAIT_DELIVER.type);
        return HttpStatus.OK.value();
    }

    /**
     * 用户通过微信支付或支付宝支付后
     * 每隔三秒就进查询该订单状态，如果该订单状态是已支付
     * 那么返回数据给到前端，前端进行判断，提示用户支付成功
     * @param orderId
     * @return
     */
    @ApiOperation(value = "根据订单 Id 查询订单状态信息", notes = "根据订单 Id 查询订单状态信息", httpMethod = "POST")
    @PostMapping("/getPaidOrderInfo")
    public IMOOCJSONResult getPaidOrderInfo(String orderId)
    {
        OrderStatus orderStatus = orderService.queryOrderStatusInfo(orderId);
        return IMOOCJSONResult.ok(orderStatus);
    }
}